/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fourbox.server;

import fourbox.FUtil;
import fourbox.Metafile;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author hartono
 */
public class ServerDownloadHandler implements Runnable {

    String username;
    public static final int TIME_OUT = 5000;
    long lastTime;
    long currTime;
    List queue;
    Socket socket;

    public ServerDownloadHandler(Socket socket, List queue, String username) {
        this.socket = socket;
        this.queue = queue;
        this.username = username;
    }

    @Override
    public void run() {
        System.out.println("Server Downloader : Thread  is started ");
        Metafile headQueue = null;
        boolean connectionOn = true;
        synchronized (queue) {
            if (queue.size() == 0) {
                try {
                    socket.close();
                    System.out.println("Server Downloader : queue is empty, no file to download");
                } catch (IOException ex) {
                    Logger.getLogger(ServerDownloadHandler.class.getName()).log(Level.SEVERE, null, ex);
                }
                return;
            } else {
                // queue not empty
                System.out.println("Server Downloader : There are " + queue.size() + " file to be downloaded");
                headQueue = (Metafile) queue.get(0);
                try {

                    DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
                    ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());

                    System.out.println("Server Downloader : Thread start receiving input stream");

                    currTime = System.currentTimeMillis();
                    lastTime = System.currentTimeMillis();
                    while (connectionOn) {
                        currTime = System.currentTimeMillis();
                        if (inputStream.available() != 0) {

                            lastTime = System.currentTimeMillis();
                            System.out.println("Server Downloader : Try to receiving file ");

                            try {
                                int index = inputStream.readInt();                                
                                Metafile metafile = (Metafile) inputStream.readObject();
                                System.out.println("Server Downloader : Downloading Metafile -> " + metafile);
                                if (metafile.equals(headQueue)) {
                                    // validate the metafile.. if same as head of queue
                                    if (headQueue.status != Metafile.DELETED) {
                                        // tidak deleted

                                        if (metafile.isFile) {
                                            // is file                                            
                                            File fo = Metafile.createFileFromMetafileServer(username, metafile); // file output path

                                            File parent = fo.getParentFile();
                                            while (!parent.exists()) {
                                                parent.mkdirs();                                                
                                            }

                                            if (!fo.exists()) {
                                                fo.createNewFile();
                                            } else {
                                                fo.delete();
                                                fo.createNewFile();
                                            }

                                            FileOutputStream fos = new FileOutputStream(fo);
                                            byte[] blockData = new byte[1];
                                            while (inputStream.available() != 0) {
                                                int len = inputStream.read(blockData);
                                                fos.write(blockData);
                                            }
                                            fos.close();


                                            // cek sum dulu
                                            if (true) {
                                                // if success, 

                                                // sent ack
                                                outputStream.writeInt(1);
                                                outputStream.write(1);
                                                outputStream.flush();
                                                System.out.println("Server Downloader : File received "+headQueue);
                                                try {
                                                    Thread.sleep(100);
                                                } catch (Exception e2) {
                                                }

                                                queue.remove(0);
                                                if (queue.size() == 0) {
                                                    connectionOn = false;
                                                } else if (queue.size() > 0) {
                                                    headQueue = (Metafile) queue.get(0);
                                                }
                                                lastTime = System.currentTimeMillis();
                                            } else {
                                                // file not received well
                                                outputStream.writeInt(1);
                                                outputStream.write(0);
                                                outputStream.flush();
                                                System.out.println("Server Downloader : File not received well "+headQueue);
                                                try {
                                                    Thread.sleep(100);
                                                } catch (Exception e2) {
                                                }
                                                lastTime = System.currentTimeMillis();
                                            }

                                        } else {
                                            //is folder
                                            File fo = Metafile.createFileFromMetafileServer(username, metafile);
                                            if (!fo.exists()) {
                                                fo.mkdirs();
                                            }
                                            outputStream.writeInt(1);
                                            outputStream.write(1);
                                            outputStream.flush();

                                            try {
                                                Thread.sleep(100);
                                            } catch (Exception e2) {
                                            }

                                            // if true
                                            queue.remove(0);
                                            if (queue.size() == 0) {

                                                connectionOn = false;
                                            } else if (queue.size() > 0) {
                                                headQueue = (Metafile) queue.get(0);
                                            }
                                            lastTime = System.currentTimeMillis();
                                            System.out.println("Server Downloader : Folder received "+headQueue);
                                        }// check tipe file
                                    } else {
                                        //  status metafile deleted
                                        File fo = Metafile.createFileFromMetafileServer(username, metafile); // file output path

                                        if (fo.exists()) {                                            
                                            boolean deleted = FUtil.deletePaths(fo.toPath());
                                            if (deleted) {
                                                outputStream.writeInt(1);
                                                outputStream.write(1);
                                                outputStream.flush();

                                                try {
                                                    Thread.sleep(100);
                                                } catch (Exception e2) {
                                                }

                                                queue.remove(0);
                                                if (queue.size() == 0) {
                                                    connectionOn = false;
                                                } else if (queue.size() > 0) {
                                                    headQueue = (Metafile) queue.get(0);
                                                }

                                                System.out.println("Server Downloader : " + fo + " deleted");
                                            } else {
                                                outputStream.writeInt(1);
                                                outputStream.write(0);
                                                outputStream.flush();
                                                System.out.println("Server Donwloader : File cannot be deleted");
                                                try {
                                                    Thread.sleep(100);
//                                                    connectionOn = false;
                                                } catch (Exception e2) {
                                                    e2.printStackTrace();
                                                    
                                                }

                                            }
                                            lastTime = System.currentTimeMillis();
                                        }

                                    }

                                } else {
                                    // sent nak , tidak sama dengan headqueue
                                    outputStream.writeInt(1);
                                    outputStream.write(0);
                                    outputStream.flush();
                                    System.out.println("Server Downloader : Not valid metafile");
                                    try {
                                        Thread.sleep(100);
                                        connectionOn = false;
                                    } catch (Exception e2) {
                                        e2.printStackTrace();
                                        connectionOn = false;
                                    }
                                    lastTime = System.currentTimeMillis();
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                                try {
                                    outputStream.writeInt(1);
                                    outputStream.write(0);
                                    outputStream.flush();

                                    try {
                                        Thread.sleep(100);
                                        connectionOn = false;
                                    } catch (Exception e2) {
                                        e2.printStackTrace();
                                        connectionOn = false;
                                    }

                                    lastTime = System.currentTimeMillis();
                                    System.out.println("Server Downloader : Msg BAD");
                                } catch (Exception e2) {
                                    e2.printStackTrace();
                                    System.out.println("Server Downloader : Disconnected with client");
                                    connectionOn = false;
                                }
                            }
                        } else {
                            // check time out
                            if (currTime - lastTime > TIME_OUT) {
                                System.out.println("Server Downloader : Thread TIME OUT");
                                connectionOn = false;
                            }
                        }

//                        try {
//                            Thread.sleep(100);
//                        } catch (InterruptedException ex) {
//                        }

                    } // connection on
                    inputStream.close();
                    outputStream.close();
                    socket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }// queue not empty
        }

        System.out.println("Server Downloader : Thread is closed");
    }
}
